﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web.Script.Serialization;

namespace Translator.GoogleTranslateApi
{
	/*{
 "data": {
  "translations": [
   {
    "translatedText": "hola mundo"
   }
  ]
 }
}
	*/

	public class GoogleTranslateApiImplementation
	{
		public const string apiUrl = "https://www.googleapis.com/language/translate/v2?key={0}&source={1}&target={2}&q={3}";

		String fromLanguage = "en"; // english
		String toLanguage = "ru"; // russian
		String apiKey = "jBw65i1kMoc1_CcpsGqevNEz"; // get key from https://code.google.com/apis/console/
		String url = null;
		String textToTranslate = null;

		public GoogleTranslateApiImplementation()
		{
			MakeUrl();
		}

		private void MakeUrl()
		{
			url = String.Format(apiUrl, apiKey, fromLanguage, toLanguage, textToTranslate);
		}

		public void SetSourceLanguage(string lang)
		{
			fromLanguage = lang;
		}

		public void SetTranslateLanguage(string lang)
		{
			toLanguage = lang;
		}

		public string GetTranslateLanguage()
		{
			return toLanguage;
		}

		/// <summary>
		/// Translates the text into specified language using google API.
		/// </summary>
		/// <param name="url">The url to make a web request to.</param>
		/// <returns>Returns the translated text</returns>
		public string Translate(string textToTranslate)
		{
			this.textToTranslate = textToTranslate;
			MakeUrl();
			string text = null;
			try
			{
				// create the web request
				WebRequest req = HttpWebRequest.Create(url);

				// set the request method
				req.Method = "GET";

				// get the response
				using (WebResponse res = req.GetResponse())
				{
					// read response stream
					// you must specify the encoding as UTF8 
					// because google returns the response in UTF8 format
					using (StreamReader sr = new StreamReader(res.GetResponseStream(), Encoding.UTF8))
					{
						// read text from response stream
						text = sr.ReadToEnd();
					}
				}
			}
			catch (Exception )
			{
				throw;
			}

			// return text to callee
			return text;
		}

		/// <summary>
		/// Translates a string into another language using Google's translate API JSON calls.
		/// <seealso>Class TranslationServices</seealso>
		/// </summary>
		/// <param name="Text">Text to translate. Should be a single word or sentence.</param>
		/// <param name="FromCulture">
		/// Two letter culture (en of en-us, fr of fr-ca, de of de-ch)
		/// </param>
		/// <param name="ToCulture">
		/// Two letter culture (as for FromCulture)
		/// </param>
		public GoogleTranslateResponse TranslateGoogleObject(string text)
		{
			string fromCulture = this.fromLanguage.ToLower();
			string toCulture = this.toLanguage.ToLower();

			// normalize the culture in case something like en-us was passed 
			// retrieve only en since Google doesn't support sub-locales
			string[] tokens = fromCulture.Split('-');
			if (tokens.Length > 1)
				fromCulture = tokens[0];

			// normalize ToCulture
			tokens = toCulture.Split('-');
			if (tokens.Length > 1)
				toCulture = tokens[0];

			string url = string.Format(@"http://translate.google.com/translate_a/t?client=j&text={0}&hl=en&sl={1}&tl={2}",
									   System.Web.HttpUtility.UrlEncode(text), fromCulture, toCulture);

			// Retrieve Translation with HTTP GET call
			string html = null;
			try
			{
				WebClient web = new WebClient();

				// MUST add a known browser user agent or else response encoding doen't return UTF-8 (WTF Google?)
				web.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0");
				web.Headers.Add(HttpRequestHeader.AcceptCharset, "UTF-8");

				// Make sure we have response encoding to UTF-8
				web.Encoding = Encoding.UTF8;
				html = web.DownloadString(url);
			}
			catch (Exception)
			{
				return null;
			}

			// Extract out trans":"...[Extracted]...","from the JSON string
			if (string.IsNullOrEmpty(html))
			{
				return null;
			}

			//return WebUtils.DecodeJsString(result);

			// Result is a JavaScript string so we need to deserialize it properly
			JavaScriptSerializer ser = new JavaScriptSerializer();
			return ser.Deserialize(html, typeof(GoogleTranslateResponse)) as GoogleTranslateResponse;
		}

		/// <summary>
		/// Translates a string into another language using Google's translate API JSON calls.
		/// <seealso>Class TranslationServices</seealso>
		/// </summary>
		/// <param name="Text">Text to translate. Should be a single word or sentence.</param>
		/// <param name="FromCulture">
		/// Two letter culture (en of en-us, fr of fr-ca, de of de-ch)
		/// </param>
		/// <param name="ToCulture">
		/// Two letter culture (as for FromCulture)
		/// </param>
		public string TranslateGoogle(string text)
		{
			string fromCulture = this.fromLanguage.ToLower();
			string toCulture = this.toLanguage.ToLower();

			// normalize the culture in case something like en-us was passed 
			// retrieve only en since Google doesn't support sub-locales
			string[] tokens = fromCulture.Split('-');
			if (tokens.Length > 1)
				fromCulture = tokens[0];

			// normalize ToCulture
			tokens = toCulture.Split('-');
			if (tokens.Length > 1)
				toCulture = tokens[0];

			string url = string.Format(@"http://translate.google.com/translate_a/t?client=j&text={0}&hl=en&sl={1}&tl={2}",
									   System.Web.HttpUtility.UrlEncode(text), fromCulture, toCulture);

			// Retrieve Translation with HTTP GET call
			string html = null;
			try
			{
				WebClient web = new WebClient();

				// MUST add a known browser user agent or else response encoding doen't return UTF-8 (WTF Google?)
				web.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0");
				web.Headers.Add(HttpRequestHeader.AcceptCharset, "UTF-8");

				// Make sure we have response encoding to UTF-8
				web.Encoding = Encoding.UTF8;
				html = web.DownloadString(url);
			}
			catch (Exception)
			{
				return null;
			}

			// Extract out trans":"...[Extracted]...","from the JSON string
			string result = System.Text.RegularExpressions.Regex.Match(html, "trans\":(\".*?\"),\"", System.Text.RegularExpressions.RegexOptions.IgnoreCase).Groups[1].Value;

			if (string.IsNullOrEmpty(result))
			{
				return null;
			}

			//return WebUtils.DecodeJsString(result);

			// Result is a JavaScript string so we need to deserialize it properly
			JavaScriptSerializer ser = new JavaScriptSerializer();
			return ser.Deserialize(result, typeof(string)) as string;
		}

		[System.Runtime.Serialization.DataContract()]
		public class GoogleTranslateResponse
		{
			[System.Runtime.Serialization.DataMember()]
			public List<Translation> sentences { get; set; }
			[System.Runtime.Serialization.DataMember()]
			public string src { get; set; }
			[System.Runtime.Serialization.DataMember()]
			public int server_time { get; set; }
		}

		[System.Runtime.Serialization.DataContract()]
		public class Translation
		{
			[System.Runtime.Serialization.DataMember()]
			public string trans { get; set; }
			[System.Runtime.Serialization.DataMember()]
			public string orig { get; set; }
			[System.Runtime.Serialization.DataMember()]
			public string translit { get; set; }
			[System.Runtime.Serialization.DataMember()]
			public string src_translit { get; set; }
		}
	}
}
